package cn.source.web.aspectj;


import cn.hutool.core.collection.CollectionUtil;
import cn.source.common.annotation.Dict;
import cn.source.common.core.domain.entity.SysDictData;
import cn.source.common.core.domain.entity.SysDictType;
import cn.source.common.core.page.TableDataInfo;
import cn.source.common.utils.Result;
import cn.source.system.service.ISysDictDataService;
import cn.source.system.service.ISysDictTypeService;
import cn.source.system.service.impl.SysDictDataServiceImpl;
import com.alibaba.fastjson2.JSONObject;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.ObjectMapper;
import lombok.extern.slf4j.Slf4j;
import net.sf.jsqlparser.expression.StringValue;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Pointcut;
import org.springframework.stereotype.Component;

import javax.annotation.Resource;
import java.lang.reflect.Field;
import java.util.*;
import java.util.logging.Logger;

@Aspect
@Component
@Slf4j
@SuppressWarnings("unchecked")
public class DictAspect {

    public static final String suffix = "_dictText";
    @Resource
    private ISysDictDataService sysDictDataService;

    /**
     * 定义切点Pointcut
     */
//    @Pointcut("execution(public * cn.source.system.service.impl.*.*ServiceImpl.*(..))")
    @Pointcut("execution(public * cn.source.web.controller.*.*Controller.*(..))")
    public void dictPoint() {
    }

    @Around("dictPoint()")
    public Object doAround(ProceedingJoinPoint pjp) throws Throwable {
        Object result = pjp.proceed();
        parseDict(result);
        return result;
    }


    private void parseDict(Object result) {
        if (result instanceof TableDataInfo) {
            List<?> rows = ((TableDataInfo) result).getRows();
            List<JSONObject> list = new ArrayList<>();
            if (rows != null) {
                for (Object row : rows) {
                    //将结果转成JSONObject
                    ObjectMapper objectMapper = new ObjectMapper();
                    String json = "{}";
                    try {
//                        log.info("进行数据字典翻译，返回值：{}", objectMapper.writeValueAsString(result));
                        json = objectMapper.writeValueAsString(row);
                    } catch (JsonProcessingException e) {
                        e.printStackTrace();
                        throw new RuntimeException("Json转换失败" + e.getMessage());
                    }


                    JSONObject jsonObject = JSONObject.parseObject(json);
                    //获取所有字段
                    Field[] fields = row.getClass().getDeclaredFields();

                    if (fields != null && fields.length != 0) {
                        Iterator<Field> iterator = Arrays.stream(fields).iterator();
                        //获取标注dict注解的字段
                        while (iterator.hasNext()) {
                            Field field = iterator.next();
                            Dict dict = field.getAnnotation(Dict.class);

                            if (dict != null) {
                                //从数据字典中查询code对应的k-v值
                                String code = field.getAnnotation(Dict.class).dicCode();
                                String key = String.valueOf(jsonObject.get(field.getName()));

                                String sysDictType = sysDictDataService.selectDictLabel(code,key);
                                jsonObject.put(field.getName() + suffix, sysDictType);
                            }
                        }
                        list.add(jsonObject);
                        ((TableDataInfo) result).setRows(list);
                    }
                }


            }
        }
    }


    /**
     * 检测返回结果集中是否包含Dict注解
     *
     * @param records
     * @return
     */
    private Boolean checkHasDict(List<Object> records) {
        if (CollectionUtil.isNotEmpty(records)) {
            for (Field field : getAllFields(records.get(0))) {
                if (!Objects.isNull(field.getAnnotation(Dict.class))) {
                    return true;
                }
            }
        }
        return false;
    }


    /**
     * 获取类的所有属性，包括父类
     *
     * @param object
     * @return
     */
    public static Field[] getAllFields(Object object) {
        Class<?> clazz = object.getClass();
        List<Field> fieldList = new ArrayList<>();
        while (clazz != null) {
            fieldList.addAll(new ArrayList<>(Arrays.asList(clazz.getDeclaredFields())));
            clazz = clazz.getSuperclass();
        }
        Field[] fields = new Field[fieldList.size()];
        fieldList.toArray(fields);
        return fields;
    }
}

